package cn.cqautotest.cqviehelper.ui.activity;

import android.annotation.SuppressLint;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.camera.core.AspectRatio;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.Preview;
import androidx.camera.core.impl.LensFacingCameraFilter;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;

import com.blankj.utilcode.util.PathUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.google.common.util.concurrent.ListenableFuture;

import java.io.File;
import java.util.concurrent.ExecutionException;

import butterknife.BindView;
import cn.cqautotest.cqviehelper.R;
import cn.cqautotest.cqviehelper.base.BaseActivity;
import cn.cqautotest.cqviehelper.utils.StringJoinUtils;

@SuppressLint("NonConstantResourceId")
public class TakePhotoActivity extends BaseActivity {

    @BindView(R.id.previewView)
    PreviewView previewView;
    @BindView(R.id.ivPhoto)
    ImageView resultImg;
    @BindView(R.id.takePhoto)
    Button takePhotoView;
    private File mImgFile;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_take_photo;
    }

    private Preview preview;
    private Camera camera;
    private ImageCapture imageCapture;

    private final int lensFacing = CameraSelector.LENS_FACING_BACK;

    @Override
    protected void initView() {
        String photoSavePath = StringJoinUtils.join(PathUtils.getExternalPicturesPath(), "/", "照骗.png");
        mImgFile = new File(photoSavePath);
        previewView.post(this::bindCamera);
    }

    @Override
    protected void initEvent() {
        takePhotoView.setOnClickListener(v -> {
            ImageCapture.Metadata metadata = new ImageCapture.Metadata();
            metadata.setReversedHorizontal(lensFacing == CameraSelector.LENS_FACING_FRONT);
            ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(mImgFile)
                    .setMetadata(metadata)
                    .build();
            if (imageCapture != null) {
                imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this),
                        new ImageCapture.OnImageSavedCallback() {
                            @Override
                            public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                                resultImg.setVisibility(View.VISIBLE);
                                Glide.with(resultImg)
                                        .load(mImgFile)
                                        //加载时不使用内存缓存
                                        .skipMemoryCache(true)
                                        //加载时不使用磁盘缓存
                                        .diskCacheStrategy(DiskCacheStrategy.NONE)
                                        //中心剪裁
                                        .centerCrop()
                                        .into(resultImg);
                            }

                            @Override
                            public void onError(@NonNull ImageCaptureException exception) {
                                exception.printStackTrace();
                            }
                        });
            }
        });
    }

    private void bindCamera() {
        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(lensFacing)
                .build();
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            initUseCase();
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                cameraProvider.unbindAll();
                camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);

                preview.setSurfaceProvider(previewView.createSurfaceProvider(camera.getCameraInfo()));

            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
        }, ContextCompat.getMainExecutor(this));
    }

    private void initUseCase() {
        int ratio = getPreviewRatio();
        int rotation = previewView.getDisplay().getRotation();

        preview = new Preview.Builder()
                .setTargetAspectRatio(ratio)
                .setTargetRotation(rotation)
                .build();

        imageCapture = new ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
                .setTargetAspectRatio(ratio)
                .setTargetRotation(rotation)
                .build();
    }

    private int getPreviewRatio() {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        previewView.getDisplay().getRealMetrics(displayMetrics);
        int width = displayMetrics.widthPixels;
        int height = displayMetrics.heightPixels;

        double previewRatio = ((double) Math.max(width, height)) / Math.min(width, height);
        if (Math.abs(previewRatio - AspectRatio.RATIO_4_3) <= Math.abs(previewRatio - AspectRatio.RATIO_16_9)) {
            return AspectRatio.RATIO_4_3;
        }
        return AspectRatio.RATIO_16_9;
    }
}